package org.alex.nettychat.netty.custom;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
import org.alex.nettychat.netty.custom.handler.*;
import org.alex.nettychat.netty.first.handler.FirstServerHandler;

/**
 * Netty 服务端
 *
 * @author : alex
 */
public class NettyServer {

    public static void main(String[] args) {
        ServerBootstrap serverBootstrap = new ServerBootstrap();

        /**
         * 1.boss对应IOServer.java中的负责接收新连接的线程，主要负责创建新连接。
         * 2.worker对应IOServer.java中的负责读取数据的线程，主要用于读取数据及业务逻辑处理。
         */
        NioEventLoopGroup boss = new NioEventLoopGroup();
        NioEventLoopGroup worker = new NioEventLoopGroup();

        serverBootstrap.group(boss, worker)
                .channel(NioServerSocketChannel.class)
                // 数据处理逻辑
                .childHandler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel channel) throws Exception {
                        // 处理粘包 半包问题
                        channel.pipeline().addLast(new Spliter());
                        channel.pipeline().addLast(new PacketDecoder());
                        channel.pipeline().addLast(new LoginRequestHandler());
                        // 新增用户认证handler
                        channel.pipeline().addLast(new AuthHandler());
                        channel.pipeline().addLast(new CreateGroupRequestHandler());
                        channel.pipeline().addLast(new JoinGroupRequestHandler());
                        channel.pipeline().addLast(new QuitGroupRequestHandler());
                        channel.pipeline().addLast(new GetGroupInfoRequestHandler());
                        channel.pipeline().addLast(new SendToGroupRequestHandler());
                        channel.pipeline().addLast(new MessageRequestHandler());
                        channel.pipeline().addLast(new PacketEncoder());
                    }
                });
        bind(serverBootstrap, 8000);

    }

    private static void bind(final ServerBootstrap serverBootstrap, final int port) {
        serverBootstrap.bind(8000).addListener(new GenericFutureListener<Future<? super Void>>() {
            @Override
            public void operationComplete(Future<? super Void> future) throws Exception {
                if (future.isSuccess()) {
                    System.out.println("端口:[" + port + "]绑定成功");
                } else {
                    System.out.println("端口:[" + port + "]绑定失败");
                    bind(serverBootstrap, port + 1);
                }
            }
        });
    }
}
